#ifndef NETSERVER_H
#define NETSERVER_H

#include "copyright.h"
#include "network.h"
#include "post.h"
#include "list.h"
#include "system.h"

//typedef for long long
typedef long long Timestamp;

//LTR table
Timestamp ltrTable[MAX_NO_OF_SERVERS] = {0, 0, 0, 0, 0};

//Pending message queue
List pendingMsgQueue;

//pending message struct
typedef struct pendingMsg_struct
{
	int forwServerId;
	int clientMachineId;
	int clientMailBoxId;
	char buffer[MaxMailSize];
}PendingMsg;

//RestockList for client program
List reStockList_kernel;


//enum to shoe the state of the lock
enum serverLockStatus {SERVERLOCKFREE, SERVERLOCKBUSY};
//class for serverLock
class serverLockObj
{
public:
	serverLockObj(char* debugName);  		// initialize lock to be FREE
    ~serverLockObj();				// deallocate lock
    char* getName() { return name; }	// debugging assist

    void Acquire(int machineId, int mailBoxId); // these are the only operations on a lock
    bool Release(int machineId, int mailBoxId); // they are both *atomic*

    bool isHeldByCurrentCaller(int machineId, int mailBoxId);	// true if the current caller
   					// holds this lock.  Useful for
   					// checking in Release, and in
   					// Condition variable ops below.

    char *name;	// for debugging
    // owner of the lock
    int ownerMachineId;
    int ownerMailBoxId;
	serverLockStatus isLockFree;// A boolean to denote whether the lock is free or some thread has used it.
								// TRUE value denotes that no thread has hold over the lock. i.e. It is FREE.
	List* lockWaitQueue;			// A Queue of reply messages
};

//structure for serverCV
class serverConditionObj
{
public:
	serverConditionObj(char* debugName);
		
	// initialize condition to
					// "no one waiting"
    ~serverConditionObj();			// deallocate the condition
    char* getName() { return (name); }

    void Wait(int conditionLock, int machineId, int mailBoxId); 	// these are the 3 operations on
					// condition variables; releasing the
					// lock and going to sleep are
					// *atomic* in Wait()
    void Signal(int conditionLock, int machineId, int mailBoxId);   // conditionLock must be held by
    void Broadcast(int conditionLock, int machineId, int mailBoxId);// the currentThread for all of
					// these operations

    char *name; //CV name. For debugging
    int waitingOnLock; //index of the lock in the lock table
	List *cvWaitQueue; //A queue of reply messages
    // plus some other stuff you'll need to define
};

//structure for serverMV
class serverMonitorVarObj
{
public:
	serverMonitorVarObj(char* debugName, int initValue);
	~serverMonitorVarObj();

	char* getName() { return (name); }
	void SetMV(int setValue, int machineId, int mailBoxId);
	void GetMV(int machineId, int mailBoxId);
private:
	char* name;
	int value;
};
typedef struct serverMVTableElement
{
	serverMonitorVarObj* sMV;
	bool valid;
	int mvCounter;

}serverMVTableObj;

typedef struct serverMVTableStruct
{
	serverMVTableObj serverMV[MAX_MVS];
	BitMap *serverMVBitMap;

	serverMVTableStruct()
	{
		for(int i=0; i<MAX_MVS; i++){
			serverMV[i].sMV = NULL;
			serverMV[i].valid = false;
			serverMV[i].mvCounter = 0;
		}
		serverMVBitMap = new BitMap(MAX_MVS);
	}
}serverMVTableTemplate;





//serverLockTable element
typedef struct serverLockTableElement
{
	serverLockObj *sLock;
	bool valid; //variable to store if the lock is valid
	int lockCounter; //counter to store the number of
					 //threads currently using the lock
}serverLockTableObj;

//serverCV table element
typedef struct serverCVTableElement
{
	serverConditionObj *sCV;
	bool valid;// variable to hold if the CV is valid
	int cvCounter; //counter to store the number of
				//threads currently using this CV
}serverCVTableObj;

//serverlock Table
typedef struct serverLockTableStruct
{
	serverLockTableObj serverLock[MAX_LOCKS];
	BitMap *serverLockBitMap;

	serverLockTableStruct()
	{
		for(int i=0; i<MAX_LOCKS; i++){
			serverLock[i].sLock = NULL;
			serverLock[i].valid = false;
			serverLock[i].lockCounter = 0;
		}
		serverLockBitMap = new BitMap(MAX_LOCKS);
	}
}serverLockTableTemplate;
//serverCVtable element
typedef struct serverCVTableStruct
{
	serverCVTableObj serverCV[MAX_CVS];
	BitMap *serverCVBitMap;

	serverCVTableStruct()
	{
		for(int i=0; i<MAX_LOCKS; i++){
			serverCV[i].sCV = NULL;
			serverCV[i].valid = false;
			serverCV[i].cvCounter = 0;
		}
		serverCVBitMap = new BitMap(MAX_CVS);
	}
}serverCVTableTemplate;

//Server lock and cv table instances
serverLockTableTemplate serverLockTable;
serverCVTableTemplate serverCVTable;
serverMVTableTemplate serverMVTable;
//reply message structure
typedef struct replyMessageStruct
{
	char data[MaxMailSize];//reply message data
	PacketHeader outPktHdr;
	MailHeader outMailHdr;
//Constructor
	replyMessageStruct()
	{
	    outPktHdr.to = -1;
	    outMailHdr.to = -1;
	    outMailHdr.from = -1;
	    outMailHdr.length = 0;
	}
}replyMessage;

#endif//end of header file
